package com.mysterymall.Common.Comp;

import cn.dev33.satoken.stp.StpUtil;

import com.mysterymall.Common.Utils.LogUtils;
import com.mysterymall.Common.Utils.Result;
import com.mysterymall.Mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Locale;

/**
 * @Description 切面日志打印
 * @Date 2022/1/7 15:26
 * @Created by LSH
 */
@Aspect
@Component
@Slf4j
public class LogAspect {

    private static Locale locale;

    @Autowired
    private MessageSource messageSource;


    @Autowired
    private UserMapper userMapper;

    /**
     * 定义切点
     */
    @Pointcut("@annotation(com.mysterymall.Common.Comp.Log)")
    public void doAspect() {
    }

    @Around("doAspect()")
    public Object doAround(ProceedingJoinPoint pjd) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = null;
        String handleUUID = "";

        if (!StpUtil.isLogin()) {
            handleUUID = "未登录";
        } else {
            handleUUID = userMapper.selectById(StpUtil.getLoginId().toString()).getUserName();
        }

        try {
            // 拦截的类
            Class clazz = pjd.getTarget().getClass();
            // 拦截的方法
            Method method = ((MethodSignature) pjd.getSignature()).getMethod();

            Log methodLog = method.getAnnotation(Log.class);
            String params = "";

            if (method != null && methodLog.argsWhith()) {
                params = Arrays.toString(pjd.getArgs());
            }
            // 方法开始前打印日志
            LogUtils.startInfo(log, method.getName(), clazz.getName(), handleUUID, params);

            // 执行拦截的方法
            result = pjd.proceed();

            // 方法结束后打印返回结果
            LogUtils.endtInfo(log, method.getName(), clazz.getName(), handleUUID, result, System.currentTimeMillis() - startTime);

        } catch (Throwable e) {
            throw e;
        }
        return result;
    }

    @Before("doAspect()")
    public void logRequestHeaders(JoinPoint joinPoint) {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        HttpServletRequest request = attributes.getRequest();

        String lang = request.getHeader("lang");

        if (lang == null) {
            // 获取Accept-Language头部信息
            lang = request.getHeader("Accept-Language");

            if (lang == null || lang.isEmpty()) {
                lang = "ms";
            } else {
                try {
                    lang = lang.substring(0, lang.indexOf(","));
                } catch (Exception e) {
                    lang = "ms";
                }
            }
        }
        switch (lang) {
            case "zh-CN":
            case "zh-Hans":
                request.setAttribute("Lang", "zh");
                break;
            case "en":
            case "en-US":
                request.setAttribute("Lang", "en");
                break;
            default:
                request.setAttribute("Lang", "ms");
                break;
        }

    }

    @AfterReturning(pointcut = "doAspect()", returning = "result")
    public void modifyResult(Object result) {

        // 获取当前请求的请求头
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String lang = (String) request.getAttribute("Lang");

        // 在Controller方法执行后拦截返回值并进行修改
        if (result instanceof Result) {
            Result originalResult = (Result) result;
            String o = (String) originalResult.get("message");

            String message ="";
            if (o != null && o.contains("-")) {
                message ="," + o.split("-")[1];
                o = o.split("-")[0];
            }
            switch (lang) {
                case "zh":
                    locale = Locale.CHINA;
                    break;
                case "en":
                    locale = Locale.US;
                    break;
                default:
                    locale = new Locale("ms");
                    break;
            }
            String localizedMessage = messageSource.getMessage(o, null, locale);
            originalResult.put("message", localizedMessage + message);
        }
    }
}
